﻿
using System;
using System.Reflection;
using My.Ioc.Core;

namespace My.Ioc.Condition
{
    sealed class PropertyInjectionInfo : InjectionSiteInfo, IInjectionInfo
    {
        readonly PropertyInfo _propertyInfo;

        public PropertyInjectionInfo(PropertyInfo propertyInfo, ObjectDescription description)
            : base(description)
        {
            _propertyInfo = propertyInfo;
        }

        #region ITargetInfo Members

        public string TargetName
        {
            get { return _propertyInfo.Name; }
        }

        public Type TargetType
        {
            get { return _propertyInfo.PropertyType; }
        }

        public int TargetMetadataToken
        {
            get { return _propertyInfo.MetadataToken; }
        }

        public ICustomAttributeProvider TargetAttributeProvider
        {
            get { return _propertyInfo; }
        }

        #endregion
    }

    sealed class ParameterInjectionInfo : InjectionSiteInfo, IInjectionInfo
    {
        readonly ParameterInfo _paramInfo;

        public ParameterInjectionInfo(ParameterInfo paramInfo, ObjectDescription description)
            : base(description)
        {
            _paramInfo = paramInfo;
        }

        public string TargetName
        {
            get { return _paramInfo.Name; }
        }

        public Type TargetType
        {
            get { return _paramInfo.ParameterType; }
        }

        public int TargetMetadataToken
        {
            get { return _paramInfo.MetadataToken; }
        }

        public ICustomAttributeProvider TargetAttributeProvider
        {
            get { return _paramInfo; }
        }
    }

    public abstract class InjectionSiteInfo : IInjectionSiteInfo
    {
        readonly ObjectDescription _description;

        protected InjectionSiteInfo(ObjectDescription description)
        {
            _description = description;
        }

        public Type SiteType
        {
            get { return _description.ConcreteType; }
        }

        public object SiteMetadata
        {
            get { return _description.Metadata; }
        }

        public ObjectDescription SiteDescription
        {
            get { return _description; }
        }
    }
}
